#include "multiconj_stock.h"
#include <iostream>
#include <sstream>
#include <string>
#include <cassert>
#include <cstdlib>

#define RUNTEST(t) { cerr << "Corriendo test " << #t << endl; t (); cerr << "..ok" << endl; }

using namespace std;


void asegurar(const multiconj_stock& ms, string s) {
	ostringstream out;
	ms.mostrar(out);
	assert(out.str()==s);
}


/******************************************************************************************/
/*                               tests sobre las funciones                                */
/******************************************************************************************/

void testVacio(){
	multiconj_stock ms(10);
	assert(ms.vacio());
	ms.agregar(9,1);
	assert(!ms.vacio());
	ms.sacar(9,3);
	ms.agregar(9,2);
	ms.agregar(2,4);
	ms.sacar(2,4);
	ms.sacar(9,2);
	assert(ms.vacio());
}

void testAgregar(){
	multiconj_stock ms(10);
	ms.agregar(3,7);
	asegurar(ms,"[0->0, 1->0, 2->0, 3->7, 4->0, 5->0, 6->0, 7->0, 8->0, 9->0]");
	ms.agregar(3,0);
	asegurar(ms,"[0->0, 1->0, 2->0, 3->7, 4->0, 5->0, 6->0, 7->0, 8->0, 9->0]");
	ms.agregar(4,6);
	asegurar(ms,"[0->0, 1->0, 2->0, 3->7, 4->6, 5->0, 6->0, 7->0, 8->0, 9->0]");	
	ms.agregar(2,42);
	asegurar(ms,"[0->0, 1->0, 2->42, 3->7, 4->6, 5->0, 6->0, 7->0, 8->0, 9->0]");
	ms.agregar(4,10);
	asegurar(ms,"[0->0, 1->0, 2->42, 3->7, 4->16, 5->0, 6->0, 7->0, 8->0, 9->0]");
	ms.agregar(3,100);
	asegurar(ms,"[0->0, 1->0, 2->42, 3->107, 4->16, 5->0, 6->0, 7->0, 8->0, 9->0]");
	ms.agregar(1,0);
	asegurar(ms,"[0->0, 1->0, 2->42, 3->107, 4->16, 5->0, 6->0, 7->0, 8->0, 9->0]");
	ms.agregar(0,1);
	asegurar(ms,"[0->1, 1->0, 2->42, 3->107, 4->16, 5->0, 6->0, 7->0, 8->0, 9->0]");
}


void testSacar(){
	multiconj_stock ms(6);
	ms.agregar(3,107);
	ms.agregar(4,6);
	ms.agregar(0,42);
	ms.agregar(5,10);
	asegurar(ms,"[0->42, 1->0, 2->0, 3->107, 4->6, 5->10]");
	ms.sacar(1,10);
	asegurar(ms,"[0->42, 1->0, 2->0, 3->107, 4->6, 5->10]");
	ms.sacar(3,100);
	asegurar(ms,"[0->42, 1->0, 2->0, 3->7, 4->6, 5->10]");
	ms.sacar(4,6);
	asegurar(ms,"[0->42, 1->0, 2->0, 3->7, 4->0, 5->10]");
	ms.sacar(5,200);
	asegurar(ms,"[0->42, 1->0, 2->0, 3->7, 4->0, 5->0]");
	ms.sacar(0,2);
	asegurar(ms,"[0->40, 1->0, 2->0, 3->7, 4->0, 5->0]");
	ms.sacar(3,7);
	asegurar(ms,"[0->40, 1->0, 2->0, 3->0, 4->0, 5->0]");
	ms.sacar(0,40);
	assert(ms.vacio());
}	

void testCardinal(){
	multiconj_stock ms(7);
	ms.agregar(0,30);
	ms.agregar(6,70);
	ms.sacar(0,12);
	assert(ms.cardinal(0)==18);
	ms.sacar(6,1);
	ms.sacar(6,2);
	ms.sacar(6,0);
	ms.agregar(6,2);
	assert(ms.cardinal(6)==69);
	assert(ms.cardinal(1)==0);
}

void testElQueMasHay(){
	multiconj_stock ms(10);
	ms.agregar(1,100);
	ms.agregar(2,101);
	ms.agregar(0,43);
	ms.agregar(9,1);
	ms.agregar(9,20);
	assert(ms.elQueMasHay()==2);
	ms.sacar(2,51);
	assert(ms.elQueMasHay()==1);
	ms.agregar(9,80);
	assert(ms.elQueMasHay()==9);
	ms.sacar(1,100);
	assert(ms.elQueMasHay()==9);
	ms.sacar(9,0);
	assert(ms.elQueMasHay()==9);
	ms.sacar(9,1);
	ms.agregar(0,100);
	assert(ms.elQueMasHay()==0);
	while(!ms.vacio())ms.sacar(ms.elQueMasHay(),ms.cardinal(ms.elQueMasHay())/2+1);
}

void testActualizarStock(){
	multiconj_stock ms(10);
	int a[]={234,645,123,653,656,356,63,26,24,95};
	ms.actualizarStock(a);
	asegurar(ms,"[0->234, 1->645, 2->123, 3->653, 4->656, 5->356, 6->63, 7->26, 8->24, 9->95]");
	assert(ms.elQueMasHay()==4);
	ms.sacar(4,4);
	assert(ms.elQueMasHay()==3);
	while(ms.elQueMasHay()!=9)ms.sacar(ms.elQueMasHay(),1);
	for(int i=0;i<10;i++)assert(ms.cardinal(i)<=95);
	
	int b[]={28,457,14,253,86,345,864,26,968,1};
	ms.actualizarStock(b);
	assert(ms.elQueMasHay()==8);
	ms.sacar(8,800);
	assert(ms.elQueMasHay()==6);
	ms.sacar(6,860);
	assert(ms.elQueMasHay()==1);
	ms.sacar(1,450);
	assert(ms.elQueMasHay()==5);
	ms.sacar(5,340);
	assert(ms.elQueMasHay()==3);
	ms.agregar(0,300);
	assert(ms.elQueMasHay()==0);
}

int main() {
	RUNTEST(testVacio);
	RUNTEST(testAgregar);
	RUNTEST(testSacar);
	RUNTEST(testCardinal);
	RUNTEST(testElQueMasHay);
	RUNTEST(testActualizarStock);
	return 0;
	
}
